﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using DSS_XNA.Engine.World;
using Microsoft.Xna.Framework.Input;

namespace DSS_XNA.Engine.Entities
{
    public abstract class Entity : IDisposable
    {
        #region Properties

        public Vector2 Position = new Vector2();

        public Vector2 Acceleration = new Vector2();

        public float WidthInMeters
        {
            get { return _widthInMeters; }
            set { _widthInMeters = value; EntityManager.Entities[this.Id]._widthInMeters = value; }
        }
        protected float _widthInMeters = 0;

        public float HeightInMeters
        {
            get { return _heightInMeters; }
            set { _heightInMeters = value; EntityManager.Entities[this.Id]._heightInMeters = value; }
        }
        protected float _heightInMeters = 0;

        public float WidthInPixels
        {
            get
            {
                return World.World.Meter * this.WidthInMeters;
            }
            set
            {
                this.WidthInMeters = value / World.World.Meter;
            }
        }

        public float HeightInPixels
        {
            get
            {
                return World.World.Meter * this.HeightInMeters;
            }
            set
            {
                this.HeightInMeters = value / World.World.Meter;
            }
        }

        public Phyics.BoundingBox BoundingBoxInPixels
        {
            get
            {
                return new Phyics.BoundingBox(this.Position.X, this.Position.Y, this.WidthInPixels, this.HeightInPixels);
            }
        }

        public string Name
        {
            get { return _name; }
            set { this.SetName(value); }
        }
        private string _name = String.Empty;

        public Guid Id
        {
            get { return _id; }
        }
        private Guid _id;

        public delegate void OnTouchDelegate(Entity sender, Entity entity);
        public event OnTouchDelegate Touch;

        #endregion

        #region Public Methods

        public Entity()
        {
            this._id = Guid.NewGuid();

            EntityManager.Add(this);
        }

        public abstract int Update(GameTime gameTime, KeyboardState ks, MouseState ms, GamePadState gs);

        public virtual void OnTouch(Entity entity)
        {
            if (Touch != null)
                Touch(this, entity);
        }

        #endregion

        #region Private Methods

        private void SetName(string value)
        {
            // we have to do this here because if we just set the property, the value does not propergate - not sure why, i thought all objects were references...
            // also, we use the actual member variable rather than the property to avoid stack overflow
            EntityManager.Remove(this);
            this._name = value;
            EntityManager.Add(this);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            EntityManager.Remove(this);
        }

        #endregion
    }
}
